package com.weed.helper;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;


/**
 * 实现类的动态调用。
 */
public class InvokerHelper {

  /**
   * 动态调用方法
   * @param c 希望调用函数（方法）所在对象
   * @param m 希望调用的方法名称
   * @param a 传递给被调用方法的参数
   * @return 函数返回值
   * @throws NoSuchMethodException
   * @throws InvocationTargetException
   * @throws IllegalAccessException
   */
  public static Object call(Object c, String m, ArgumentHolder a) throws
      NoSuchMethodException, InvocationTargetException, IllegalAccessException {

    //由于java支持方法名称的重载同一类中出现多于一个的同名函数），
    //所以getMethod方法使用两个参数：字符串形式的方法名称和数组形式
    //的调用参数类列表。返回值为类Method的一个对象,该对象和将要被
    //调用的方法相关联
    Method meth = c.getClass().getMethod(m, a.getArgumentClasses());
    //通过类Method对象的invoke方法动态调用希望调用的方法
    return (meth.invoke(c, a.getArguments()));
  }
  /**
   * 用于执行指定的方法。
   * 例如：call("com.weed.config.hello(123,444);"
   * @param command String
   * @return Object
   * @throws NoSuchMethodException
   * @throws InvocationTargetException
   * @throws IllegalAccessException
   */
  public static Object call(String command) throws
     NoSuchMethodException, InvocationTargetException, IllegalAccessException,
      ClassNotFoundException, InstantiationException {
     int lastIndexof = command.lastIndexOf(".");
     int rigthBracketLength = command.indexOf("(");
     int leftBracketLength = command.indexOf(")");
     String clazz = command.substring(0,lastIndexof);
     String method = command.substring(lastIndexof + 1,rigthBracketLength);
     String param = command.substring(rigthBracketLength +1,leftBracketLength);
     String[] params = param.split(",");
     ArgumentHolder ah = new ArgumentHolder();
     Class classObject = Class.forName(clazz);
     Method[] methods = classObject.getMethods();
     Method methodObject = null;
     for (int index =0;index <methods.length ;index ++ ) {
       if( methods[index].getName().equals(method)){
         methodObject = methods[index];
         break;
       }
     }
     Type[] types = methodObject.getGenericParameterTypes();
     for (int index=0;index < params.length ;index ++ ) {
       System.err.println("" + types[index]);
       ah.setArgument(params[index]);
     }

     return call(classObject.newInstance(),method,ah);
  }

  public static Object call(Object c, String m) throws
      NoSuchMethodException, InvocationTargetException, IllegalAccessException {

    //由于java支持方法名称的重载同一类中出现多于一个的同名函数），
    //所以getMethod方法使用两个参数：字符串形式的方法名称和数组形式
    //的调用参数类列表。返回值为类Method的一个对象,该对象和将要被
    //调用的方法相关联
    Method meth = c.getClass().getMethod(m, null);
    //通过类Method对象的invoke方法动态调用希望调用的方法
    return (meth.invoke(c,null));
  }

  public static boolean isMethod(Object c, String m, ArgumentHolder a) throws
      InvocationTargetException, IllegalAccessException {
    boolean bMethod = false;
    try {
      Method meth = c.getClass().getMethod(m, a.getArgumentClasses());
      bMethod = true;
    }
    catch (NoSuchMethodException e) {
      System.out.print(e.toString());
      ;
    }
    finally {
      return bMethod;
    }
  }
  /**
   * 指定的对象是否包含指定的方法。
   * @param c Object
   * @param m String
   * @return boolean
   * @throws InvocationTargetException
   * @throws IllegalAccessException
   */
  public static boolean isMethod(Object c, String m) throws
      InvocationTargetException, IllegalAccessException {
    boolean bMethod = false;
    try {
      Method meth = c.getClass().getMethod(m, null);
      bMethod = true;
    }
    catch (NoSuchMethodException e) {
//      System.out.print(e.toString());
      ;
    }
    finally {
      return bMethod;
    }
  }

  public static void main(String[] args) throws NoSuchMethodException,
      InstantiationException, ClassNotFoundException {
    try {
//      System.err.println("Config.start = " +InvokerHelper.isMethod(new Config(), "start"));
//      System.err.println("Config.lastModifiedTime = " +InvokerHelper.isMethod(new Config(), "lastModifiedTime"));
//      System.err.println("Config.start = " +InvokerHelper.isMethod(new Config(), "start"));
//      System.err.println("Config.lastModifiedTime = " +InvokerHelper.isMethod(new Config(), "lastModifiedTime"));
//        ArgumentHolder param = new ArgumentHolder(2);
//        param.setArgument(0,new String("Good "));
//        param.setArgument(1,new String("body!"));
//        System.err.println("print = " + InvokerHelper.call(new Config(),"Hello",param));
        System.err.println("print=" + InvokerHelper.call("com.weed.helper.Config.Hello(good ,body!)"));
    }
    catch (IllegalAccessException ex) {
    }
    catch (InvocationTargetException ex) {
    }
  }

}
